package org.misalen.web.service.pay.alipay;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.misalen.utils.DateUtil;
import org.misalen.web.service.file.impl.OssFileImpl;
import org.springframework.stereotype.Service;

/**
 * 支付宝支付相关实现
 * 
 * "aliPay" : { "rsaPrivate" :
 * "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCZ35dVLJPWenphJVIe4A90liwBfSCt6wzjVPmwnqU0NkKetmcyufG2+RuvBjCvo8pvQt7/XORtVSpvrDmMB0GMBwscOTesSVe7uIA15LzPrnAu+ct/KRp+bqwWuR1aNFx8BMDR0471xn2LneMxLC+qHETn6IpGmltnvhr/Ky53AxhT8EdMOALWzr1g3ojI4TqSRvjxptGHMKlad0pLHQns6SroOyAO0LtSPTpvfZ0VCRDpZEco6IRC7DW7JvymWS8Pd87zYJa6lkOfiW3gMw6akrhRAXvBJ+3fZHBapjELfx4Zw045iHPYc7SY2reG3AVs8OWldUKz+xP8eNzLIKsjAgMBAAECggEAE42eJWysvKyDsKSVcub2D9KldOr5pCAiWyEJObBvPdtHS/PR2VhXpvCw2+TleuxNZSYSQFEFlf8kjVxNU8X4Rlr+xm9e673GMEyZvj963slD6DRF77rBax+VLq4HVNciiX/xILjJieHXQk6l+DGtPOiquO2L5LzosJ4vwA00slq31rYgA8w/h7wlCRPwpujQy+EBnLY7etGkceRQMLE+VWbXXBdPR/bH9jM4B5A6FRCM5yMPKkf7sFlORI1qOen6xLC8780tGmuXccybaeCiSM6tPzN9/M0ZkW+mdWhulpREqK5esO8r07b7fwTluj4NcnL+JvMzHfYZYlfyL9ylgQKBgQDPhOFVMrRfp4wq+6GnOyOMlzcugn/10Zax5V5+LDMwG9cq/ytY3mBbjtSr1n+dvfjRhPwPit3N/+JRwHpPzFjREqRLfipUntN636EbHZiteoQMGZJwKZab0zyhgiCn765D48NXcIFaEkuT4A1IuoHB+8dYJ3X2S0b5dhqrodCquQKBgQC90lFh7tbmsH/nkXkT4Q/TN0GLDsHHwfxbMPRWaxqSitMk9Cs3mIWGdxOGJqH5RoGOGGt3ZEcGLMCmUdyqqLBM0HQMK90V2xAw2leQST3JWZKLVC7yf91b7d7GFUwdLmrxa8M94HSiK2NrDOTlHGfMZxDxRmDdN/l48YwKEQCmuwKBgQChBEbfF5ezPMrasyKMIqwDs3VCpklpUDWwVPvLxLn3EzMSDqnwq6Nyh1Hm/2lH2RaOY7Q8zxApfel6a3G8Jx+nIeLPHNb1j8Mh7RERfBZyTMTWqqTgWLSetfmui8yQ4b2CueBhIU+MtvNjiw5jpyt1e8oCUaQK9f/dIlGxaL4DKQKBgFcrjlP66pVl2FbvZzrJ0AqfBWpmjHa/jrQR9yL4bGt/dRczSeVuFWN6q2yfsSJYToaCkFdzpWoggxfd4Ag/Dzc3QxOT0SOIRhcpLa0E9WrRx4pUTnruXSkqQ3OTtDBycIoNgsuXl/ghFLbEZRkRwlkLu6wRNcphOh9gTX8R78qhAoGBAJ2lDlzNPJHXTCeuVxK4ihxx/habL/XdvOiHI85vfvNnJ0BC30bQ0LYbyyzBrENDrgFGcANpEfoDtP/im0PAV+hviU9z1GQNZ//juJJN0TNCd/KLHEF3j02+W6TVJPnUFeOxp+TsUAzSZ7F7+sd6GVROHP6faZW7P4svervvrGq6",
 * "partner" : "2088621762379461", "seller" : "1395888133@qq.com",
 * "payNotifyUrl" :
 * "http://www.yuebaonline.com:8081/yueba-server/v1/pay/alipay", "rsaPublic" :
 * "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmd+XVSyT1np6YSVSHuAPdJYsAX0gresM41T5sJ6lNDZCnrZnMrnxtvkbrwYwr6PKb0Le/1zkbVUqb6w5jAdBjAcLHDk3rElXu7iANeS8z65wLvnLfykafm6sFrkdWjRcfATA0dOO9cZ9i53jMSwvqhxE5+iKRppbZ74a/ysudwMYU/BHTDgC1s69YN6IyOE6kkb48abRhzCpWndKSx0J7Okq6DsgDtC7Uj06b32dFQkQ6WRHKOiEQuw1uyb8plkvD3fO82CWupZDn4lt4DMOmpK4UQF7wSft32RwWqYxC38eGcNOOYhz2HO0mNq3htwFbPDlpXVCs/sT/HjcyyCrIwIDAQAB",
 * "notifyUrl" : "" },
 *
 */
@Service
public class AliPayImpl {
	String appId = null;
	String rsaPrivate = null;
	static Properties p = new Properties();
	static {
		InputStream in = OssFileImpl.class.getClassLoader().getResourceAsStream("pro.properties");
		try {
			p.load(in);
			in.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public AliPayImpl() {
		appId = p.getProperty("pay.alipay.appId");
		rsaPrivate = p.getProperty("pay.alipay.rsaPrivate");
	}

	/**
	 * 得到移动端支付需要的字符串
	 * 
	 * @throws UnsupportedEncodingException
	 */
	public String getAlipayInfo(AliPayParam myParam, String notifyUrl) throws UnsupportedEncodingException {
		Map<String, String> keyValues = new HashMap<String, String>();
		keyValues.put("app_id", appId);
		keyValues.put("method", "alipay.trade.app.pay");
		keyValues.put("format", "JSON");
		keyValues.put("charset", "utf-8");
		keyValues.put("sign_type", "RSA2");
		keyValues.put("timestamp", DateUtil.formatDate(new Date(), "yyyy-MM-dd HH:mm:dd"));
		keyValues.put("version", "1.0");
		keyValues.put("biz_content", myParam.toString());
		keyValues.put("notify_url", notifyUrl);
		List<String> keys = new ArrayList<String>(keyValues.keySet());
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < keys.size() - 1; i++) {
			String key = keys.get(i);
			String value = keyValues.get(key);
			sb.append(buildKeyValue(key, value, true));
			sb.append("&");
		}

		String tailKey = keys.get(keys.size() - 1);
		String tailValue = keyValues.get(tailKey);
		sb.append(buildKeyValue(tailKey, tailValue, true));
		String privateKey = rsaPrivate;
		String sign = getSign(keyValues, privateKey, true);
		final String orderInfo = sb.toString() + "&" + sign;

		return orderInfo;
	}

	public static String getSign(Map<String, String> map, String rsaKey, boolean rsa2)
			throws UnsupportedEncodingException {
		List<String> keys = new ArrayList<String>(map.keySet());
		// key排序
		Collections.sort(keys);

		StringBuilder authInfo = new StringBuilder();
		for (int i = 0; i < keys.size() - 1; i++) {
			String key = keys.get(i);
			String value = map.get(key);
			authInfo.append(buildKeyValue(key, value, false));
			authInfo.append("&");
		}

		String tailKey = keys.get(keys.size() - 1);
		String tailValue = map.get(tailKey);
		authInfo.append(buildKeyValue(tailKey, tailValue, false));

		String oriSign = SignUtils.sign(authInfo.toString(), rsaKey, rsa2);
		String encodedSign = URLEncoder.encode(oriSign, "UTF-8");

		return "sign=" + encodedSign;
	}

	private static String buildKeyValue(String key, String value, boolean isEncode) {
		StringBuilder sb = new StringBuilder();
		sb.append(key);
		sb.append("=");
		if (isEncode) {
			try {
				sb.append(URLEncoder.encode(value, "UTF-8"));
			} catch (UnsupportedEncodingException e) {
				sb.append(value);
			}
		} else {
			sb.append(value);
		}
		return sb.toString();
	}

}
